package xj.graph2d.app.prop;

import static xj.graph2d.app.resources.Resources.getResourceString;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.AbstractButton;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;

import xj.graph2d.ArrowAttr;
import xj.graph2d.Command;
import xj.graph2d.DrawAttr;
import xj.graph2d.DrawCanvas;
import xj.graph2d.DrawShape;
import xj.graph2d.OpenShape;
import xj.graph2d.SimpleDrawDocument;
import xj.graph2d.SimpleDrawView;
import xj.graph2d.app.DrawAction;
import xj.graph2d.app.DrawApp;
import xj.graph2d.command.SetArrowsCommand;
import xj.graph2d.command.SetAttrCommand;
import xj.graph2d.dialog.DialogPanel;
import xj.graph2d.dialog.TitledDialogPanel;

public class LineOptionListener 
  extends DrawAction 
  implements ActionListener {

  protected String[] lineStyleNames;

  protected String[] lineCapNames;

  protected int[] lineCapValues;

  protected String[] lineJoinNames;

  protected int[] lineJoinValues;

  protected String[] arrowNames;

  // tool bar icons and buttons

  protected LineWidthIcon lineWidthIcon;
  protected TailArrowIcon tailArrowIcon;
  protected HeadArrowIcon headArrowIcon;
  protected CapIcon  capIcon;
  protected JoinIcon joinIcon;

  protected AbstractButton lineWidthButton, tailArrowButton, headArrowButton, capButton, joinButton;

  @Override
  protected void init() {
    SimpleDrawView view = main.getView();
    headArrowAttr = view.getHeadArrowAttr();
    tailArrowAttr = view.getTailArrowAttr();
    attr = view.getDrawAttr();

    lineStyleNames = new String[] {
      getResourceString("Solid.text"),
      getResourceString("Dashed.text"),
      getResourceString("DashDot.text"),
      getResourceString("DashDotDot.text"),
      getResourceString("Dotted.text")
    };

    lineCapNames = new String[] {
      getResourceString("Butt.text"),
      getResourceString("Round.text"),
      getResourceString("Square.text")
    };

    lineCapValues = new int[] { 
      DrawAttr.LINE_CAP_BUTT,
      DrawAttr.LINE_CAP_ROUND, DrawAttr.LINE_CAP_SQUARE
    };

    lineJoinNames = new String[] {
      getResourceString("Miter.text"),
      getResourceString("Round.text"),
      getResourceString("Bevel.text")
    };

    lineJoinValues = new int[] { 
      DrawAttr.LINE_JOIN_MITER,
      DrawAttr.LINE_JOIN_ROUND,
      DrawAttr.LINE_JOIN_BEVEL
    };

    arrowNames = new String[] {
      getResourceString("NoArrow.text"),
      getResourceString("LineArrow.text"),
      getResourceString("HollowTriangle.text"),
      getResourceString("FilledTriangle.text"),
      getResourceString("HollowDiamond.text"),
      getResourceString("FilledDiamond.text"),
      getResourceString("HollowDot.text"),
      getResourceString("FilledDot.text"),
      getResourceString("CrossDot.text")
    };

    lineWidthIcon = (LineWidthIcon) DrawApp.getIcon("lineWidthIcon");
    tailArrowIcon = (TailArrowIcon) DrawApp.getIcon("tailArrowIcon");
    headArrowIcon = (HeadArrowIcon) DrawApp.getIcon("headArrowIcon");
    capIcon = (CapIcon) DrawApp.getIcon("capIcon");
    joinIcon = (JoinIcon) DrawApp.getIcon("joinIcon");
  }

  class LineStyleOptionPanel extends DialogPanel {

    public LineStyleOptionPanel(String name, String title) { 
      super(name, title);
      JLabel widthLable = new JLabel(getResourceString("LineWidth.text")
				     + " ");
      lineWidthModel = new SpinnerNumberModel(1, 1, 10, 1);
      lineWidth = new JSpinner(lineWidthModel);
      widthDefault = new JButton(getResourceString("Default.text"));
      widthDefault.addActionListener(new ActionListener() {
	public void actionPerformed(ActionEvent e) {
	  lineWidth.setValue(new Integer(1));
	}
      });

      JLabel styleLable = new JLabel(getResourceString("LineStyle.text") + " ");
      lineStyle = new JComboBox();
      for (int i = 0; i < lineStyleNames.length; i++) {
	lineStyle.addItem(lineStyleNames[i]);
      }
      styleDefault = new JButton(getResourceString("Default.text"));
      styleDefault.addActionListener(new ActionListener() {
	public void actionPerformed(ActionEvent e) {
	  lineStyle.setSelectedIndex(0);
	}
      });

      JLabel capLable = new JLabel(getResourceString("LineCap.text") + " ");
      lineCap = new JComboBox();
      for (int i = 0; i < lineCapNames.length; i++) {
	lineCap.addItem(lineCapNames[i]);
      }
      capDefault = new JButton(getResourceString("Default.text"));
      capDefault.addActionListener(new ActionListener() {
	public void actionPerformed(ActionEvent e) {
	  lineCap.setSelectedIndex(0);
	}
      });

      JLabel joinLable = new JLabel(getResourceString("LineJoin.text") + " ");
      lineJoin = new JComboBox();
      for (int i = 0; i < lineJoinNames.length; i++) {
	lineJoin.addItem(lineJoinNames[i]);
      }
      joinDefault = new JButton(getResourceString("Default.text"));
      joinDefault.addActionListener(new ActionListener() {
	public void actionPerformed(ActionEvent e) {
	  lineJoin.setSelectedIndex(0);
	}
      });

      addRow(widthLable, lineWidth, widthDefault);
      addRow(styleLable, lineStyle, styleDefault);
      addRow(capLable, lineCap, capDefault);
      addRow(joinLable, lineJoin, joinDefault);

      setPreferredSize(new Dimension(350, 200));
      setOption();
    }

    @Override
    public void setOption() {
      if (attr != null) {
	int w = attr.getPenSize();
	int s = attr.getLineStyle();
	int c = attr.getLineCap();
	int j = attr.getLineJoin();
	lineWidthModel.setValue(new Integer(w));
	lineStyle.setSelectedIndex(s);
	lineCap.setSelectedIndex(c - DrawAttr.LINE_CAP_BUTT);
	lineJoin.setSelectedIndex(j - DrawAttr.LINE_JOIN_MITER);
      }
    }

    @Override
    public void applyOption() {
      int w = lineWidthModel.getNumber().intValue();
      int s = lineStyle.getSelectedIndex();
      int c = lineCap.getSelectedIndex();
      int j = lineJoin.getSelectedIndex();
      // update system attribute
      attr.setPenSize(w);
      attr.setLineStyle(s);
      attr.setLineCap(lineCapValues[c]);
      attr.setLineJoin(lineJoinValues[j]);

      lineWidthIcon.setWidth(w);
      lineWidthIcon.setStyle(s);
      capIcon.setCapType(lineCapValues[c]);
      joinIcon.setJoinType(lineJoinValues[j]);            
      lineWidthButton.repaint();
      capButton.repaint();
      joinButton.repaint();

      // update current shape
      SimpleDrawDocument doc = main.getDoc();
      SimpleDrawView view = main.getView();
      if (doc != null) {
	DrawShape curShape = doc.getSelectedShape();
	if (curShape != null) {
	  DrawAttr curAttr = curShape.getDrawAttr();
	  if (curAttr != null) {
	    Command cmd = new SetAttrCommand(view, doc, curShape);
	    doc.addCommand(cmd);

	    curAttr.setPenSize(w);
	    curAttr.setLineStyle(s);
	    curAttr.setLineCap(lineCapValues[c]);
	    curAttr.setLineJoin(lineJoinValues[j]);
	    curShape.calculateBounds();
	    DrawCanvas canvas = view.getCanvas();
	    canvas.repaintShape(curShape);
	  }
	}
      }
    }

    protected SpinnerNumberModel lineWidthModel;

    protected JSpinner lineWidth;

    protected JComboBox lineStyle;

    protected JComboBox lineCap;

    protected JComboBox lineJoin;

    protected JButton widthDefault;

    protected JButton styleDefault;

    protected JButton capDefault;

    protected JButton joinDefault;
  }

  class ArrowOptionPanel extends DialogPanel {

    public ArrowOptionPanel(String name, String title) { 
      super(name, title);
      JLabel headLable = new JLabel(getResourceString("HeadArrow.text") + " ");
      headArrow = new JComboBox();
      for (int i = 0; i < arrowNames.length; i++) {
	headArrow.addItem(arrowNames[i]);
      }
      headArrowDefault = new JButton(getResourceString("Default.text"));
      headArrowDefault.addActionListener(new ActionListener() {
	public void actionPerformed(ActionEvent e) {
	  headArrow.setSelectedIndex(0);
	}
      });
      JLabel headSizeLable = new JLabel(getResourceString("HeadSize.text")
					+ " ");
      headSizeModel = new SpinnerNumberModel(8, 4, 40, 4);
      headSize = new JSpinner(headSizeModel);
      headSizeDefault = new JButton(getResourceString("Default.text"));
      headSizeDefault.addActionListener(new ActionListener() {
	public void actionPerformed(ActionEvent e) {
	  headSize.setValue(new Integer(8));
	}
      });

      JLabel tailLable = new JLabel(getResourceString("TailArrow.text") + " ");
      tailArrow = new JComboBox();
      for (int i = 0; i < arrowNames.length; i++) {
	tailArrow.addItem(arrowNames[i]);
      }
      tailArrowDefault = new JButton(getResourceString("Default.text"));
      tailArrowDefault.addActionListener(new ActionListener() {
	public void actionPerformed(ActionEvent e) {
	  tailArrow.setSelectedIndex(0);
	}
      });
      JLabel tailSizeLable = new JLabel(getResourceString("TailSize.text") + " ");
      tailSizeModel = new SpinnerNumberModel(8, 4, 40, 4);
      tailSize = new JSpinner(tailSizeModel);
      tailSizeDefault = new JButton(getResourceString("Default.text"));
      tailSizeDefault.addActionListener(new ActionListener() {
	public void actionPerformed(ActionEvent e) {
	  tailSize.setValue(new Integer(8));
	}
      });

      addRow(headLable, headArrow, headArrowDefault);
      addRow(headSizeLable, headSize, headSizeDefault);
      addRow(tailLable, tailArrow, tailArrowDefault);
      addRow(tailSizeLable, tailSize, tailSizeDefault);

      setOption();
    }

    @Override
    public void setOption() {
      int i = headArrowAttr.getType().ordinal();
      headArrow.setSelectedIndex(i);
      int s = (int) headArrowAttr.getSize();
      headSizeModel.setValue(new Integer(s));
      i = tailArrowAttr.getType().ordinal();
      tailArrow.setSelectedIndex(i);
      s = (int) tailArrowAttr.getSize();
      tailSizeModel.setValue(new Integer(s));
    }

    @Override
    public void applyOption() {
      int i = headArrow.getSelectedIndex();
      headArrowAttr.setType(ArrowAttr.ArrowType.getArrowType(i));
      int s = headSizeModel.getNumber().intValue();
      headArrowAttr.setSize(s);
      headArrowIcon.setArrowType(ArrowAttr.ArrowType.getArrowType(i)); 

      i = tailArrow.getSelectedIndex();
      tailArrowAttr.setType(ArrowAttr.ArrowType.getArrowType(i));
      s = tailSizeModel.getNumber().intValue();
      tailArrowAttr.setSize(s);
      tailArrowIcon.setArrowType(ArrowAttr.ArrowType.getArrowType(i)); 

      tailArrowButton.repaint();
      headArrowButton.repaint();

      // update current shape
      SimpleDrawDocument doc = main.getDoc();
      SimpleDrawView view = main.getView();
      if (doc != null) {
	DrawShape curShape = doc.getSelectedShape();
	if (curShape instanceof OpenShape) {
	  Command cmd = new SetArrowsCommand(view, doc, curShape);
	  doc.addCommand(cmd);

	  ((OpenShape) curShape).addArrows(headArrowAttr, tailArrowAttr);
	  curShape.calculateBounds();
	  DrawCanvas canvas = view.getCanvas();
	  canvas.repaintShape(curShape);
	}
      }
    }

    protected JComboBox headArrow;

    protected JComboBox tailArrow;

    protected SpinnerNumberModel headSizeModel;

    protected SpinnerNumberModel tailSizeModel;

    protected JSpinner headSize;

    protected JSpinner tailSize;

    protected JButton headArrowDefault;

    protected JButton tailArrowDefault;

    protected JButton headSizeDefault;

    protected JButton tailSizeDefault;

  }

  //protected OptionDialog optionDialog = null;
  protected TitledDialogPanel optionDialog = null;
  protected boolean showTitlePane = false;

  protected ArrowAttr headArrowAttr = null;

  protected ArrowAttr tailArrowAttr = null;

  protected DrawAttr attr = null;

  public void actionPerformed(ActionEvent e) {
    if (optionDialog == null) {
      String lineStyleDialogTitle = getResourceString("LineStyleDialog.title");
      String lineStyleHeader = getResourceString("LineStyleDialog.header");
      String[] lineStyleText = new String[] { 
	getResourceString("LineStyleDialog.text1"),
	getResourceString("LineStyleDialog.text2"),	
      };
      //Icon icon = main.getIcon("NewWizIcon");

      DialogPanel[] options = {
	new LineStyleOptionPanel(getResourceString("LineStyles.title"), 
				 showTitlePane ? null : lineStyleText[0]),
	new ArrowOptionPanel(getResourceString("Arrows.title"),
			     showTitlePane ? null : lineStyleText[1]),
      };

      optionDialog = new TitledDialogPanel(main.getJFrame(), 
					   JOptionPane.OK_CANCEL_OPTION,
					   null, options);
      optionDialog.setTitle(lineStyleDialogTitle);
      if (showTitlePane) { 
	optionDialog.setTitlePaneText(lineStyleHeader, lineStyleText, null);
      }

      lineWidthButton = (AbstractButton) main.findToolButton("mainToolbar", "LineWidthSelection");
      tailArrowButton = (AbstractButton) main.findToolButton("mainToolbar", "TailArrowSelection");
      headArrowButton = (AbstractButton) main.findToolButton("mainToolbar", "HeadArrowSelection");
      capButton = (AbstractButton) main.findToolButton("mainToolbar", "CapSelection");
      joinButton = (AbstractButton) main.findToolButton("mainToolbar", "JoinSelection");
    }
    optionDialog.setOptions();
    optionDialog.showOptionDialog();
  }

}
